/**
 *
 * @param {Function} pathRender 渲染路线名称列的方法
 * @param {Function} operateRender 渲染操作列的方法
 * @param {Function} lossPriceRender 渲染网损折价列的方法
 * @returns antd的table配置列数组
 */
export const getPathTableColumnsConfig = (pathRender, operateRender, lossPriceRender) => {
  // 第一列，编号
  let orderColumnConfig = {
    title: '线路编号',
    render: (text, record, index) => `${index + 1}`,
    width: '6.5%',
    align: 'center',
  };
  // 第二列路线名称
  let pathColumnConfig = {
    title: '路线名称',
    className: 'pathName',
    dataIndex: 'name',
    align: 'center',
    width: '11%',
  };
  pathRender ? (pathColumnConfig.render = pathRender) : true;
  // 第三列，网损
  let lossColumnConfig = {
    title: '网损(%)',
    dataIndex: 'loss',
    align: 'center',
    width: '19%',
    render: (text, record, index) => (parseFloat(text) * 100).toFixed(2),
  };
  // 第四列，输配电价
  let sendPriceColumnConfig = {
    title: '输配电价(元/MWh)',
    dataIndex: 'sendPrice',
    align: 'center',
    width: '19%',
    render: (text, record, index) => parseFloat(text).toFixed(2),
  };
  // 第五列，降额电价
  let downPrice = {
    title: '降价额度(元/MWh)',
    dataIndex: 'downPrice',
    align: 'center',
    width: '19%',
    render: (text, record, index) => parseFloat(text).toFixed(2),
  };
  // 第六列，网损折价
  let lossPriceColumnConfig = {
    title: '网损折价(元/MWh)',
    dataIndex: 'lossPrice',
    align: 'center',
    width: '19%',
    render: lossPriceRender
      ? lossPriceRender
      : (text, record, index) =>
          index == 0 || text == 0 || text == '-' ? '-' : parseFloat(text).toFixed(2),
  };
  // 第七列，操作列，如果需要的话
  let operateColumnConfig = {
    title: '删除',
    dataIndex: 'operate',
    align: 'center',
    render: operateRender,
    width: '6.5%',
  };
  let resultConfig = [
    orderColumnConfig,
    pathColumnConfig,
    lossColumnConfig,
    sendPriceColumnConfig,
    downPrice,
    lossPriceColumnConfig,
  ];
  operateRender && resultConfig.push(operateColumnConfig);
  return resultConfig;
};

/**
 * 格式化当前时间，不支持年，支持到毫秒
 * @param {String} pattern 格式化时间的格式
 * @returns 格式化后的时间字符串
 */
export const formatNowTime = (pattern) => {
  let now = new Date();
  let fmt = pattern;
  let obj = {
    'M+': now.getMonth() + 1, //月份
    'd+': now.getDate(), //日
    'H+': now.getHours(), //小时
    'm+': now.getMinutes(), //分
    's+': now.getSeconds(), //秒
    'q+': Math.floor((now.getMonth() + 3) / 3), //季度
    S: now.getMilliseconds(), //毫秒
  };
  if (/(y+)/.test(fmt))
    fmt = fmt.replace(RegExp.$1, (now.getFullYear() + '').substr(4 - RegExp.$1.length));
  for (var k in obj) {
    if (new RegExp('(' + k + ')').test(fmt))
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length == 1 ? obj[k] : ('00' + obj[k]).substr(('' + obj[k]).length),
      );
  }
  return fmt;
};

/**
 * 正向计算外送价格路线网损折价
 * @param {Array} paths 路线信息数组
 * @param {Number} calculateIndex 要计算的元素的索引
 * @param {Number} initNum 计算初始值
 */
export const forwardCalculateLossPrice = (paths, calculateIndex, initNum) => {
  let num = initNum;
  // 校验是否初始值是否有效
  if (Number.isNaN(num)) {
    paths[calculateIndex].lossPrice = '-';
    return [...paths];
  }
  num -= 0;
  paths
    .filter((item, index) => index < calculateIndex)
    .forEach(({ sendPrice, lossPrice }, i) => {
      num += sendPrice;
      if (i != 0) {
        num += lossPrice;
      }
    });

  let targetPath = paths[calculateIndex];
  let { loss } = targetPath;
  targetPath.lossPrice = (num * loss) / (1.0 - loss);
  paths[calculateIndex] = targetPath;
  return [...paths];
};

/**
 * 反向计算外送价格路线网损折价
 * @param {Array} paths 路线信息数组
 * @param {Number} calculateIndex 要计算的元素索引
 * @param {Number} initNum 计算初始值
 */
export const backCalculateLossPrice = (paths, calculateIndex, initNum) => {
  let num = initNum;
  // 校验是否初始值是否有效
  if (Number.isNaN(num)) {
    paths[calculateIndex].lossPrice = '-';
    return [...paths];
  }

  paths.forEach(({ sendPrice, downPrice, lossPrice }, index) => {
    num -= downPrice;
    if (index == calculateIndex) {
      num -= sendPrice;
    } else if (index > calculateIndex) {
      num -= sendPrice;
      num -= lossPrice;
    }
  });
  let targetPath = paths[calculateIndex];
  let { loss } = targetPath;
  targetPath.lossPrice = (num * loss).toFixed(2);
  paths[calculateIndex] = targetPath;
  return [...paths];
};

/**
 * 删除旧行后的网损折价更新
 * @param {Array} paths 路线信息数组
 * @param {Number} removeIndex 删除行的索引
 * @param {Object} condition 计算条件 {price,type}
 */
export const calculateRemoveRowLossPrice = (condition, removeIndex, paths) => {
  let { price, type } = condition;
  let result = paths;
  if (type == 'send') {
    for (let index = removeIndex; index <= paths.length - 1; index++) {
      result = forwardCalculateLossPrice(result, index, price);
    }
    return result;
  } else {
    for (let index = paths.length - 1; index >= 0; index--) {
      result = backCalculateLossPrice(result, index, price);
    }
    return result;
  }
};

/**
 * 创建新行后的网损折价更新
 * @param {Array} paths 路线信息数组
 * @param {Object} condition 计算条件 {price,type}
 */
export const calculateNewRowLossPrice = (condition, paths) => {
  let { price, type } = condition;
  if (type == 'send') {
    return forwardCalculateLossPrice(paths, paths.length - 1, price);
  } else {
    let result = paths;
    for (let index = paths.length - 1; index >= 0; index--) {
      result = backCalculateLossPrice(result, index, price);
    }
    return result;
  }
};

/**
 * 更新旧行后的网损折价更新
 * @param {Array} paths 路线信息数组
 * @param {Number} modifyIndex 更新行的索引
 * @param {Object} condition 计算条件 {price,type}
 */
export const calculateModifyRowLossPrice = (condition, modifyIndex, paths) => {
  let { price, type } = condition;
  let result = paths;
  if (type == 'send') {
    for (let index = modifyIndex; index <= paths.length - 1; index++) {
      result = forwardCalculateLossPrice(result, index, price);
    }
    return result;
  } else {
    for (let index = paths.length - 1; index >= 0; index--) {
      result = backCalculateLossPrice(result, index, price);
    }
    return result;
  }
};

/**
 * 重新计算全部网损折价
 * @param {Array} paths 路线信息数组
 * @param {Object} condition 计算条件 {price,type}
 */
export const calculateAllLossPirce = (condition, paths) => {
  let { price, type } = condition;
  let result = paths;
  if (type == 'send') {
    for (let index = 0; index < paths.length; index++) {
      result = forwardCalculateLossPrice(paths, index, price);
    }
    return result;
  } else {
    for (let index = paths.length - 1; index >= 0; index--) {
      result = backCalculateLossPrice(paths, index, price);
    }
    return result;
  }
};

/**
 * 将路径价格基本信息转换成antd-table的单行属性json
 * @param {Array} pathArr 路径数组
 * @param {Number} index 数组索引下标
 * @param {Number} key table的遍历索引key
 * @returns object
 */
export const castPathInfoToTableObj = (pathArr, index) => {
  let { lineName, gridLoss, transmissionDistributionPrice, priceReductionLimit } = pathArr[index];
  return {
    key: `${+new Date()}`,
    name: lineName,
    loss: gridLoss,
    sendPrice: transmissionDistributionPrice,
    downPrice: priceReductionLimit,
    lossPrice: 0,
  };
};

/**
 * 验证iage字符串是否合法
 * @param {String} price 价格字符串
 */
export const validatePirce = (price) => {
  let result = price;
  result.replace(/[^\d^\.]+/g, '');
  result = result.replace(/[\u4e00-\u9fa5]+/g, ''); //验证非汉字
  result = result.replace(/[^\d.]/g, ''); //清除"数字"和"."以外的字符
  result = result.replace(/^\./g, ''); //验证第一个字符是数字而不是
  result = result.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.'); //只保留第一个小数点, 清除多余的
  result = result.replace(/^(\-)*(\d+)\.(\d{3}).*$/, '$1$2.$3'); //只能输入6个小数
  return result;
};
